#include "cv.h"
#include "highgui.h"
#include <string>
#define PIXEL_COUNT 5
using namespace std;

/**
 * simple blur
 * @param: IplImage* image : input image
 * @return: IplImage* image : output image
 */
IplImage* simpleSmooth(IplImage* image){
	//create the output image
	IplImage* imageOut = cvCreateImage(cvGetSize(image), image->depth, image->nChannels);
	//do smoothing
	cvSmooth(image, imageOut, CV_BLUR, PIXEL_COUNT, PIXEL_COUNT);
	return imageOut;
}

/**
 * median blur
 * @param: IplImage* image : input image
 * @return: IplImage* image : output image
 */
IplImage* medianBlur(IplImage* image){
	//create the output image
	IplImage* imageOut = cvCreateImage(cvGetSize(image), image->depth, image->nChannels);
	//do smoothing
	cvSmooth(image, imageOut, CV_MEDIAN, PIXEL_COUNT, PIXEL_COUNT);
	return imageOut;
}

/**
 * gaussBlur
 * @param: IplImage* image : input image
 * @return: IplImage* image : output image
 */
IplImage* gaussBlur(IplImage* image){
	//create the output image
	IplImage* imageOut = cvCreateImage(cvGetSize(image), image->depth, image->nChannels);
	//do smoothing
	cvSmooth(image, imageOut, CV_GAUSSIAN, PIXEL_COUNT, PIXEL_COUNT);
	return imageOut;
}

/**
 * main
 * @param: 
 * @return: 
 */
void main(){
	string filePath = "test.jpg";
	//define window
	string windowNameIn = "in";
	string windowNameOutSimple = "Simple out";
	string windowNameOutMedian = "Median out";
	string windowNameOutGauss = "Gauss out";
	cvNamedWindow(windowNameIn.data());
	cvNamedWindow(windowNameOutSimple.data());
	cvNamedWindow(windowNameOutMedian.data());
	cvNamedWindow(windowNameOutGauss.data());
	//load image
	IplImage* image = cvLoadImage(filePath.data());
	//show the input image
	cvShowImage(windowNameIn.data(), image);

	//handle image
	IplImage* imageOutSimple = NULL;
	IplImage* imageOutMedian = NULL;
	IplImage* imageOutGauss = NULL;
	imageOutSimple = simpleSmooth(image);
	imageOutMedian = medianBlur(image);
	imageOutGauss = gaussBlur(image);

	//show output image
	cvShowImage(windowNameOutSimple.data(), imageOutSimple);
	cvShowImage(windowNameOutMedian.data(), imageOutMedian);
	cvShowImage(windowNameOutGauss.data(), imageOutGauss);
	//waitKey
	cvWaitKey(0);
	//release;
	cvReleaseImage(&image);
	cvReleaseImage(&imageOutSimple);
	cvReleaseImage(&imageOutMedian);
	cvReleaseImage(&imageOutGauss);
	cvDestroyWindow(windowNameIn.data());
	cvDestroyWindow(windowNameOutSimple.data());
	cvDestroyWindow(windowNameOutMedian.data());
	cvDestroyWindow(windowNameOutGauss.data());
}